import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;


public class Leetcode662 {
    public int widthOfBinaryTree(TreeNode root) {
        int res = 1;
        List<Object[]> list = new ArrayList<>();
        list.add(new Object[]{1, root});
        while (!list.isEmpty()) {
            List<Object[]> cpList = new ArrayList<>();

            for (Object[] objects : list) {
                int index = (int) objects[0];
                TreeNode val = (TreeNode) objects[1];
                if (val.left != null) {
                    cpList.add(new Object[]{index * 2, val.left});
                }

                if (val.right != null) {
                    cpList.add(new Object[]{index * 2 + 1, val.right});
                }
            }

            if (cpList.size() != 0) {
                res = Math.max(res, (int) cpList.get(cpList.size() - 1)[0] - (int) cpList.get(0)[0] + 1);
            }

            list = cpList;
        }

        return res;
    }

    public int widthOfBinaryTree1(TreeNode root) {
        if (root == null) {
            return 0;
        }

        int res = 0;
        root.val = 0;
        Queue<TreeNode> queue = new ArrayDeque<>();
        queue.add(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            int start = 0;
            int end;
            for (int i = 0; i < size; i++) {
                TreeNode cur = queue.poll();
                if (i == 0) {
                    start = cur.val;
                } else if (i == size - 1) {
                    end = cur.val;
                    res = Math.max(res, end - start + 1);
                }

                if (cur.left != null) {
                    cur.left.val = 2 * cur.val;
                    queue.add(cur.left);
                }
                if (cur.right != null) {
                    cur.right.val = 2 * cur.val + 1;
                    queue.add(cur.right);
                }
            }

        }
        return res;
    }
}
